package com.zelo.blog.server.security;

import com.zelo.blog.server.client.AuthenticationCenterClient;
import com.zelo.blog.server.tools.JsonTools;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.stereotype.Component;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.Objects;

/**
 * @author zhanglu
 * @description
 * @date 2017/11/19 14:38
 */
@Component
@Slf4j
public class TokenProcessFilter extends BasicAuthenticationFilter {
    @Autowired
    private TokenUtil tokenUtil;
    @Autowired
    private AuthenticationCenterClient authenticationCenterClient;

    public TokenProcessFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        Cookie[] cookieArr =  request.getCookies();
        if (null == cookieArr || cookieArr.length <= 0) {
            log.debug("Cookie was not found,the url is {},method is {}", request.getRequestURL(),request.getMethod());
            super.doFilterInternal(request, response, chain);
            return;
        }

        String token = Arrays.stream(cookieArr).filter(cookie -> tokenUtil.getCookieAuth().equalsIgnoreCase(cookie.getName()))
                .map(Cookie::getValue).findFirst().orElse(null);
        log.debug("doFilter get token from cookie is {}", token);
        if (StringUtils.isBlank(token)) {
            log.debug("token was not found，this url:{} is permit all!", request.getRequestURL());
            super.doFilterInternal(request, response, chain);
            return;
        }
        AuthenticationUser authenticationUser = tokenUtil.parserToken(token);
        if (Objects.isNull(authenticationUser)) {// 这里可能用户私自修改token，防止被恶意攻击
            log.debug("token is wrong,so get null from parserToken");
            super.doFilterInternal(request, response, chain);
            return;
        }
        log.debug("the user info is {}", JsonTools.showJSONStringFormat(authenticationUser));
        long expire = authenticationUser.getExpireDate().getTime();
        long now = System.currentTimeMillis();
        if (now > expire) {
            log.debug("the token is time out,go to DB to check the expire date is time out also");
            String newToken = authenticationCenterClient.refreshToken(token);
            if (StringUtils.isBlank(newToken)) {
                log.debug("the DB token is time out also,please login!");
                tokenUtil.removeResponseAuthCookie(response);
                tokenUtil.removeRequestAuthCookie(request);
                super.doFilterInternal(request, response, chain);
                return;
            }
            tokenUtil.setCookie(response, newToken);
        }
        super.doFilterInternal(request, response, chain);
    }
}
